ECS Fargate で「Capacity is unavailable at this time」になったときの対処方法
困っていた内容
ECS の「スケジュールされたタスク」で Fargate タスクを実行しています。
先日、タスクが実行されていない事象が発生し、調査したところ CloudTrail の RunTask イベントに次のエラーが記録されていました。
Capacity is unavailable at this time. Please try again later or in a different availability zone
原因と対処方法を教えてください。
どう対応すればいいの?
AWS 側でタスク実行に必要なリソースが確保できなかった旨のエラーです。
時間をおいて、再度 ECS タスクの実行をお試しください。
Troubleshoot unavailable capacity for Fargate tasks | AWS re:Post
If Amazon ECS doesn't have the capacity to launch a Fargate task, then the RunTask API fails with the following error message:
"Capacity is unavailable at this time. Please try again later or in a different availability zone"
EC2 同様、Fargate でも AWS 側でタスク実行に必要な空きリソースがない場合は、キャパシティ不足のエラーが発生する場合があります。
通常、時間をおいて再実行で対処できますが、状況に応じて次の内容も併せてお試しください。
- 別のアベイラビリティーゾーンを指定する(別 AZ の VPC サブネットを指定する)
- タスク定義で異なるタスクサイズを指定する
また、Step Functions を利用することで再実行を自動化することも可能です。
Step Functions で自動リトライを構築してみた
構成図
手順
- Step Functions の作成
- IAM ポリシーの修正
- EventBridge の作成
事前準備として、ECS クラスターやタスク定義、サブネットは用意します。
準備が完了したら、以下手順を進めます。
Step Functions の作成
Step Functions コンソールを開き、「ステートマシンの作成」をクリックします。
「Blank」を選択して「選択」をクリックします。
「コード」を選択します。
定義(赤枠で囲った部分)に、次のコードを参考に ECS タスクを起動するフローを入力します。
{
"Comment": "Running Fargate tasks with automatic retry when capacity is insufficient",
"StartAt": "Run an ECS Task",
"States": {
"Run an ECS Task": {
"Type": "Task",
"Resource": "arn:aws:states:::ecs:runTask.sync",
"Parameters": {
"LaunchType": "FARGATE",
"Cluster": "<クラスター ARN>",
"TaskDefinition": "<タスク定義 ARN>:<リビジョン番号>",
"NetworkConfiguration": {
"AwsvpcConfiguration": {
"Subnets": [
"<サブネットID>"
],
"SecurityGroups": [
"<セキュリティグループID>"
],
"AssignPublicIp": "ENABLED"
}
}
},
"Retry": [
{
"ErrorEquals": [
"ECS.AmazonECSException"
],
"IntervalSeconds": 60,
"MaxAttempts": 3,
"BackoffRate": 3
}
],
"End": true
}
}
}
「設定」をクリックします。
「ステートマシン名」に任意の名前を入力し「作成」を選択します。
「確認」をクリックします。
IAM ポリシーの修正
IAM ロールやポリシーが自動で作成されますが、iam:PassRole
が不足しているので追加します。
参考:Step FunctionsからECS RunTaskしようとしたら「ECS.AccessDeniedException」と出た時の対処法 | DevelopersIO
「ステートマシンは正常に作成されました」の表示を確認したら、「設定」タブから「IAM で表示」をクリックします。
アタッチされたポリシーをクリックします。
「編集」をクリックします。
「新しいステートメントを追加」をクリックします。
追加されたステートメント(赤枠で囲った部分)を、次の内容に修正します。
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": "*"
}
「次へ」をクリックします。
「変更を保存」をクリックします。
ポリシーが正常に更新されたことを確認します。
EventBridge の作成
Step Functions コンソール(作成したステートマシン)の「アクション」から「EventBridge ルールを作成」を選択します。
「名前」に任意の名前を入力し、「スケジュール」を選択します。「EventBridge Scheduler で続行」をクリックします。
実行間隔となるスケジュールパターンを入力し、「次へ」をクリックします。
「テンプレート化されたターゲット」から「StartExecution」を選択します。
作成したステートマシンを選択して「スケジュールの確認と作成をスキップ」を選択します。
「スケジュールを作成」をクリックします。
スケジュールが作成されたことを確認します。
スケジュールされたタスク同様、時間になると自動的に ECS タスクが実行されます。
キャパシティ不足が発生した際は、Retry
フィールドの内容に応じて自動再試行が実行されます。
参考資料
- Troubleshoot unavailable capacity for Fargate tasks | AWS re:Post
- Step Functions ワークフローでのエラーの処理 - AWS Step Functions
- Step Functions を使用して Amazon ECSまたは Fargate タスクを実行する - AWS Step Functions
- ECSの「スケジュールされたタスク」で稀に ECS タスクが実行されていないときの対処方法 | DevelopersIO
- Step Functions で ECS タスク(Fargate)を定期実行してみる | DevelopersIO